package com.wshoto.ocean.service.common.service;

import com.baomidou.mybatisplus.core.conditions.*;
import com.baomidou.mybatisplus.core.metadata.*;
import com.wshoto.mybatis.autoconfigure.util.*;

import java.io.*;
import java.util.*;

/**
 * 通用CRUD操作
 *
 * @author Lee
 */
public interface SimpleGenericDataBaseService {

    /**
     * 插入给定的实体对象
     *
     * @param var1 要插入的实体对象
     * @param <T>
     * @return 执行状态
     */
    <T> boolean save(T var1);


    /**
     * 批量插入默认实现
     *
     * @param entityList 要插入的实体对象集合
     * @param clazz      要插入的实例对象类型
     * @param <T>
     * @return 执行状态
     */
    default <T> boolean saveBatch(Collection<T> entityList, Class clazz) {
        return this.saveBatch(entityList, 1000, clazz);
    }

    /**
     * 批量插入
     *
     * @param var1  要插入的实体对象集合
     * @param var2  批量插入的数量/集合长度
     * @param clazz 要插入的实例对象类型
     * @param <T>
     * @return 执行状态
     */
    <T> boolean saveBatch(Collection<T> var1, int var2, Class clazz);

    /**
     * 插入或更新给定的实体对象
     *
     * @param var1 要更新或插入的实体对象
     * @param <T>
     * @return 执行状态
     */
    <T> boolean saveOrUpdate(T var1);

    /**
     * 批量插入或更新默认实现
     *
     * @param entityList 要插入或更新的实体对象集合
     * @param clazz      要插入或更新的实例对象类型
     * @param <T>
     * @return 执行状态
     */
    default <T> boolean saveOrUpdateBatch(Collection<T> entityList, Class clazz) {
        return this.saveOrUpdateBatch(entityList, 1000, clazz);
    }

    /**
     * 批量插入或更新
     *
     * @param var1  要插入或更新的实体对象集合
     * @param var2  要插入或更新的数量/集合长度
     * @param clazz 要插入或更新的实体对象集合
     * @param <T>
     * @return 执行状态
     */
    <T> boolean saveOrUpdateBatch(Collection<T> var1, int var2, Class clazz);

    /**
     * 通过主键删除
     *
     * @param var1  主键ID
     * @param clazz 要删除的实体对象类型
     * @param <T>
     * @return 执行状态
     */
    <T> boolean deleteById(Serializable var1, Class clazz);

    /**
     * 通过Map批量删除
     *
     * @param var1  Map对象，键为表字段名称，值为该字段要匹配的条件值
     * @param clazz 要删除的实体对象类型
     * @return 执行状态
     */
    boolean deleteByMap(Map<String, Object> var1, Class clazz);

    /**
     * 通过条件批量删除
     *
     * @param var1 删除的条件对象
     * @param <T>
     * @return 执行状态
     */
    <T> boolean delete(Wrapper<T> var1);

    /**
     * 通过主键集合批量删除
     *
     * @param var1  要删除的实体对象主键集合
     * @param clazz 要删除的实体对象类型
     * @param <T>
     * @return 执行状态
     */
    <T> boolean deleteByIds(Collection<? extends Serializable> var1, Class clazz);

    /**
     * 通过主键更新
     *
     * @param var1 要更新的包含主键的实体对象
     * @param <T>
     * @return 执行状态
     */
    <T> boolean updateById(T var1);

    /**
     * 通过条件批量更新
     *
     * @param var1 要更新的结果实体对象
     * @param var2 更新条件
     * @param <T>
     * @return 执行状态
     */
    <T> boolean update(T var1, Wrapper<T> var2);

    /**
     * 通过主键批量更新默认实现
     *
     * @param entityList 要更新的包含主键的实体对象集合
     * @param clazz      要更新的实体对象类型
     * @param <T>
     * @return 执行状态
     */
    default <T> boolean updateBatchById(Collection<T> entityList, Class clazz) {
        return this.updateBatchById(entityList, 1000, clazz);
    }

    /**
     * 通过主键批量更新
     *
     * @param var1  要更新的包含主键的实体对象集合
     * @param var2  批量更新的数量/集合长度
     * @param clazz 要更新的实体对象类型
     * @param <T>
     * @return 执行状态
     */
    <T> boolean updateBatchById(Collection<T> var1, int var2, Class clazz);

    /**
     * 通过主键查询实体对象
     *
     * @param var1  主键ID
     * @param clazz 要查询的实体对象类型
     * @param <T>
     * @return 实体对象结果
     */
    <T> T getById(Serializable var1, Class clazz);

    /**
     * 通过主键集合查询实体对象集合
     *
     * @param var1  主键集合
     * @param clazz 要查询的实体对象类型
     * @param <T>
     * @return 实体对象集合
     */
    <T> Collection<T> listByIds(Collection<? extends Serializable> var1, Class clazz);

    /**
     * 通过Map查询实体对象集合
     *
     * @param var1  Map对象，键为表字段名称，值为该字段要匹配的条件值
     * @param clazz 要查询的实体对象类型
     * @param <T>
     * @return 实体对象集合
     */
    <T> Collection<T> listByMap(Map<String, Object> var1, Class clazz);

    /**
     * 通过条件查询单个实体对象默认实现
     *
     * @param queryWrapper 查询条件对象
     * @param <T>
     * @return 实体对象结果
     */
    default <T> T getOne(Wrapper<T> queryWrapper) {
        return this.getOne(queryWrapper, true);
    }

    /**
     * 通过条件查询单个实体对象
     *
     * @param var1 查询条件对象
     * @param var2 是否忽略异常
     * @param <T>
     * @return 实体对象结果
     */
    <T> T getOne(Wrapper<T> var1, boolean var2);

    /**
     * 通过条件查询Map形式的单个实体对象
     *
     * @param var1 条件对象
     * @param <T>
     * @return Map形式的结果对象
     */
    <T> Map<String, Object> getMap(Wrapper<T> var1);


    /**
     * 通过条件查询Object形式的单个实体对象默认实现
     *
     * @param queryWrapper 条件对象
     * @param <T>
     * @return Object形式的结果对象
     */
    default <T> Object getObj(Wrapper<T> queryWrapper) {
        return WrapperUtils.getObject(this.listObjs(queryWrapper));
    }

    /**
     * 数量统计
     *
     * @param var1 条件对象
     * @param <T>
     * @return 结果数量
     */
    <T> int count(Wrapper<T> var1);

    /**
     * 数量统计默认实现
     *
     * @param entity 包含条件的实体对象
     * @param <T>
     * @return 结果数量
     */
    default <T> int count(T entity) {
        return this.count(WrapperUtils.query(entity));
    }

    /**
     * 条件查询
     *
     * @param var1 条件对象
     * @param <T>
     * @return 实体对象集合
     */
    <T> List<T> list(Wrapper<T> var1);

    /**
     * 条件查询默认实现
     *
     * @param entity 包含条件的实体对象
     * @param <T>
     * @return 实体对象集合
     */
    default <T> List<T> list(T entity) {
        return this.list(WrapperUtils.query(entity));
    }

    /**
     * 条件查询
     *
     * @param var1 条件对象
     * @param <T>
     * @return Map类型的结果集合
     */
    <T> List<Map<String, Object>> listMaps(Wrapper<T> var1);

    /**
     * 条件查询默认实现
     *
     * @param entity 包含条件的实体对象
     * @param <T>
     * @return Map类型的结果集合
     */
    default <T> List<Map<String, Object>> listMaps(T entity) {
        return this.listMaps(WrapperUtils.query(entity));
    }

    /**
     * 条件查询
     *
     * @param var1 条件对象
     * @param <T>
     * @return Object类型结果集合
     */
    <T> List<T> listObjs(Wrapper<T> var1);

    /**
     * 条件查询默认实现
     *
     * @param entity 包含条件的实体对象
     * @param <T>
     * @return Object类型结果集合
     */
    default <T> List<T> listObjs(T entity) {
        return this.listObjs(WrapperUtils.query(entity));
    }

    /**
     * 分页条件查询
     *
     * @param var1 分页对象
     * @param var2 条件对象
     * @param <T>
     * @return 实体对象分页集合
     */
    <T> IPage<T> page(IPage<T> var1, Wrapper<T> var2);

    /**
     * 分页条件查询默认实现
     *
     * @param page   分页对象
     * @param entity 包含条件的实体对象
     * @param <T>
     * @return 实体对象分页集合
     */
    default <T> IPage<T> page(IPage<T> page, T entity) {
        return this.page(page, WrapperUtils.query(entity));
    }

    /**
     * 分页条件查询
     *
     * @param var1 分页对象
     * @param var2 条件对象
     * @param <T>
     * @return Map分页集合
     */
    <T> IPage<Map<String, Object>> pageMaps(IPage<T> var1, Wrapper<T> var2);

    /**
     * 分页条件查询默认实现
     *
     * @param page   分页对象
     * @param entity 包含条件的实体对象
     * @param <T>
     * @return Map分页集合
     */
    default <T> IPage<Map<String, Object>> pageMaps(IPage<T> page, T entity) {
        return this.pageMaps(page, WrapperUtils.query(entity));
    }
}
